﻿using System;
using UnityEditor;
using UnityEngine;
using System.Collections;
using UnityEditorInternal;
using System.Collections.Generic;

namespace Miao.Editor
{
    public class EditorList<T>
    {
        public Func<Type, object> AddElementFunc;//如何添加元素，有些元素可能没有无参的构造函数，这时候就需要开发者自行实现添加
        public Action<Rect, int, List<T>> FooterDrawDelegate;//底部绘制函数
        public Action<Rect, List<T>> TitleDrawDelegate = delegate { };//标题绘制函数
        public Action<Rect, T, int> ElementDrawDelegate = delegate { };//元素绘制函数,必须实现

        public float dragButtonHeight { get { return 20; } }//拖拽按钮宽度
        public float titleHeight { get { return reorderableList.headerHeight; } set { reorderableList.headerHeight = value; } }//标题高度

        private readonly IList list;
        private readonly Type listType;
        private readonly ReorderableList reorderableList;
        private int removeIndex = -1;

        public EditorList(IList list, bool isDraggable = false)
        {
            this.list = list;
            listType = list.GetType();
            if (listType.IsArray) throw new Exception("EditorList don't support Array! Plese use List");
            reorderableList = new ReorderableList(list, typeof(T));
            reorderableList.draggable = isDraggable;
            reorderableList.drawHeaderCallback += DrawTitle;
            reorderableList.drawFooterCallback += DrawFooter;
            reorderableList.drawElementCallback += DrawElement;
            reorderableList.drawNoneElementCallback += delegate { };
        }

        public void Draw()
        {
            if (removeIndex != -1)
            {
                list.RemoveAt(removeIndex);
                removeIndex = -1;
            }
            EditorGUILayout.BeginVertical();
            reorderableList.DoLayoutList();
            EditorGUILayout.EndVertical();
        }
        public void RemoveElementAt(int index)
        {
            removeIndex = index;
        }

        private void DrawTitle(Rect rect)//绘制标题
        {
            TitleDrawDelegate(rect, (List<T>)list);
        }
        private void DrawElement(Rect rect, int index, bool isActive, bool isFocused)//绘制元素
        {
            rect.height = EditorGUIUtility.singleLineHeight;
            ElementDrawDelegate(rect, (T)list[index], index);
        }
        private void DrawFooter(Rect rect)//绘制结尾
        {
            if (FooterDrawDelegate == null) DefaultFooterDraw(rect);
            else FooterDrawDelegate(rect, reorderableList.index, (List<T>)list);

        }
        private void DefaultFooterDraw(Rect rect)//默认结尾绘制函数
        {
            float currentY = rect.y;
            float currentX = rect.x;
            float currentWidth = rect.width / 3;
            float currentHeight = EditorGUIUtility.singleLineHeight;

            if (GUI.Button(new Rect(currentX, currentY, currentWidth, currentHeight), "Add", EditorStyles.miniButtonLeft))
            {
                if (AddElementFunc != null)
                {
                    object element = AddElementFunc(listType.GetGenericArguments()[0]);
                    reorderableList.index = list.Add(element);
                }
                else AddElement();
            }
            currentX += currentWidth;
            if (GUI.Button(new Rect(currentX, currentY, currentWidth, currentHeight), "Remove", EditorStyles.miniButtonMid) && list.Count != 0)
            {
                int currentIndex = reorderableList.index;
                if (currentIndex != -1)
                {
                    list.RemoveAt(currentIndex);
                    reorderableList.index = currentIndex - 1;
                }
                else list.RemoveAt(0);
            }
            currentX += currentWidth;
            if (GUI.Button(new Rect(currentX, currentY, currentWidth, currentHeight), "Clear", EditorStyles.miniButtonRight) && list.Count != 0)
            {
                if (EditorUtility.DisplayDialog("ClearList", "Are you sure want clear the List?", "Yes", "No")) list.Clear();
            }
        }
        private void AddElement()//默认添加元素函数
        {
            Type elementType = listType.GetGenericArguments()[0];
            if (elementType.GetConstructor(Type.EmptyTypes) == null)//获取无参构造函数
                throw new Exception($"[EditorList.AddElement] Error : Type {elementType.ToString()} no default constructor,Can not add element.");
            reorderableList.index = list.Add(Activator.CreateInstance(elementType));
        }
    }
}